package com.example.fixsys.common;

import java.util.Arrays;
import java.util.Random;

public class SelfMathUtil {

    private static final int number = 10;
    private static final int letter = 26;
    private char[] hashArr = new char[64];
    private int[] hashSelf = new int[64];
    private int[] hash_map = new int[128];

    /* 生成哈希对照 */
    public SelfMathUtil(){
        CreateHashArr();
        CreateHashSelf();
    }

    private void CreateHashArr() {
        hashArr[0] = '<';
        hash_map['<'] = 0;
        int currentIndex = 1;
        for (int n = 0; n < CharacterType.NUMBER.getCount(); n++) {
            char currentChar = (char) ('0' + n);
            hashArr[currentIndex] = currentChar;
            hash_map[currentChar] = currentIndex;
            currentIndex++;
        }
        for (int l = 0; l < CharacterType.LETTER.getCount(); l++) {
            char lowerCaseChar = (char) ('a' + l);
            char upperCaseChar = (char) ('A' + l);
            hashArr[currentIndex] = lowerCaseChar;
            hash_map[lowerCaseChar] = currentIndex;
            currentIndex++;
            hashArr[currentIndex] = upperCaseChar;
            hash_map[upperCaseChar] = currentIndex;
            currentIndex++;
        }
        hashArr[currentIndex] = '>';
        hash_map['>'] = currentIndex;
    }

    private char Int2Char(int rand){
        return hashArr[rand];
    }

    private int Char2Int(int rand){
        return hash_map[rand];
    }

    /* 随机生成密码 */
    public String createPassword(int passwordLength) {
        Random random = new Random();
        StringBuilder sb = new StringBuilder(passwordLength);
        for (int i = 0; i < passwordLength; i++) {
            sb.append(Int2Char(random.nextInt(62) + 1));
        }
        return sb.toString();
    }

    private void CreateHashSelf(){
        int w = 64, l = 1, i = 1;
        hashSelf[0] = 0;
        while((w = w / 2) > 0){
            for(int j = 0; j < l; j++){
                hashSelf[i++] = w + hashSelf[j];
            }
            l = l * 2;
        }
    }

    /* 密码按位倒置 */
    private int MazeRule(int pswLetter){
        return hashSelf[pswLetter];
    }

    /* 敏感数据加密 */
    public String setMaze(String str){
        String newStr = "";
        for(int i = 0; i < str.length(); i++)
            newStr = newStr + Int2Char(1^(MazeRule(1^Char2Int(str.charAt(i)))));
        return newStr;
    }

    private String generateString(int x, int i){
        Random random = new Random();
        int m, n;
        int j = random.nextInt(2);
        String littleStr = "";
        if(j == 0){
            m = (i + x + 1) % 64;
        }
        else{
            int c = random.nextInt(64);
            m = (i + x + c + 1) % 64;
            littleStr += Int2Char(c);
        }
        n = (i + ((i / 64) + 1) * 64 - x + 1) % 64;
        if(i % 2 == 0)
            littleStr = Int2Char(m) + (Int2Char(n) + littleStr);
        else
            littleStr = littleStr + Int2Char(n) + Int2Char(m);
        return littleStr;
    }

    private String setLongerMaze(String str){
        String newStr = "";
        for(int i = 0; i < str.length(); i++){
            String littleStr = generateString(Char2Int(str.charAt(i)), i);
            newStr = i % 2 == 0 ? littleStr + newStr : newStr + littleStr;
        }
        return Int2Char(str.length()) + newStr;
    }

    private String getShorterMaze(String str){
        String newStr = "";
        int pswLength = Char2Int(str.charAt(0));
        str = str.substring(1,str.length());
        for(int i = pswLength - 1;i >= 0; i--){
            if(i % 2 == 0){
                newStr = Int2Char((i - Char2Int(str.charAt(1)) + 65) % 64) + newStr;
                if((Char2Int(str.charAt(0)) + Char2Int(str.charAt(1))) % 64 == 2 * (i + 1) % 64)
                    str = str.substring(2, str.length());
                else str = str.substring(3, str.length());
            }
            else{
                newStr = Int2Char((i - Char2Int(str.charAt(str.length() - 2)) + 65) % 64) + newStr;
                if((Char2Int(str.charAt(str.length() - 1)) + Char2Int(str.charAt(str.length() - 2))) % 64 == 2 * (i + 1) % 64)
                    str = str.substring(0, str.length() - 2);
                else str = str.substring(0, str.length() - 3);
            }
        }
        return newStr;
    }

    public String crazyMaze(String str){
        return setMaze(setLongerMaze(str));
    }

    public String solveMaze(String str) {
        return getShorterMaze(setMaze(str));
    }
}